package so.sao.code.service.domain.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.sigmatrix.sc.qrcode.service.feign.QRCodeFeignClient;
import com.sigmatrix.sc.qrcode.service.feign.entity.QRCodeSyncRequest;
import com.sigmatrix.sc.qrcode.service.feign.entity.Response;

import so.sao.code.service.config.CloudContainerConfig;
import so.sao.code.service.domain.ValidateUtils;
import so.sao.code.service.domain.entity.RangeActivation;
import so.sao.code.service.domain.entity.SeqmentCustomField;
import so.sao.code.service.domain.entity.TagBatch;
import so.sao.code.service.domain.entity.TagBatchConfig;
import so.sao.code.service.domain.event.RangeActivationActiveEvent;
import so.sao.code.service.infrastructure.enums.ActivationMethod;
import so.sao.code.service.infrastructure.enums.CodeMessage;
import so.sao.code.service.infrastructure.enums.OPERATION;
import so.sao.code.service.infrastructure.enums.TagRangeStatus;
import so.sao.code.service.repository.RangeActivationDao;
import so.sao.code.service.repository.SeqmentCustomFieldDao;
import so.sao.code.service.repository.TagBatchConfigDao;
import so.sao.data.dto.response.EnterpriseDTO;
import so.sao.data.feign.client.EnterpriseClient;
import so.sao.ffw.dto.message.TagRangeActivationMessage;
import so.sao.ffw.dto.request.TagBatchSequenceInfo;
import so.sao.ffw.dto.request.TagBatchStatusRequest;
import so.sao.ffw.dto.response.TagBatchStatusResponse;
import so.sao.ffw.feign.client.TagBatchReportClient;
import so.sao.ffw.feign.client.TagRangeActivationClient;
import so.sao.nosql.datastore.enums.tag.TagStatus;
import so.sao.top.core.util.rest.RestException;

/**
 * Created by Administrator on 2017/9/13.
 */
@Service
public class RangeActivativeDomainService {
	@Autowired
	RangeActivationDao rangeActivationDao;
	@Autowired
	ApplicationEventPublisher publisher;
	@Autowired
	TagRangeActivationClient tagRangeActivationClient;
	@Autowired
	TagBatchReportClient tagBatchReportClient;
	@Autowired
	private QRCodeFeignClient qrCodeFeignClient;
	@Autowired
	private CloudContainerConfig cloudContainerConfig;
	@Autowired
	TagBatchConfigDao tagBatchConfigDao;
	@Autowired
	EnterpriseClient enterprisesClient;
	@Autowired
	SeqmentCustomFieldDao seqmentCustomFieldDao;
	// @Autowired
	// TagTaskDao tagTaskDao;

	/**
	 * 批量激活码段是设置激活码段的开始结束序号
	 */
	public void mulitDefaultSequNum(TagBatch tagBatch, RangeActivation rangeActivation) {
		rangeActivation.setAll(true);
		switch (tagBatch.getType()) {
		// 标
		case NORMAL:
			rangeActivation.setSeqnumStart(tagBatch.getSeqnumStart());
			rangeActivation.setSeqnumEnd(tagBatch.getSeqnumEnd());
			break;
		// 套
		case PACKAGE:
			rangeActivation.setSeqnumStart(tagBatch.getSeqnumStart());
			rangeActivation.setSeqnumEnd(tagBatch.getSeqnumStart() + tagBatch.getUnitCount() - 1);
			break;
		// 双
		case DUPLICATE:
			rangeActivation.setSeqnumStart(tagBatch.getSeqnumStart());
			rangeActivation.setSeqnumEnd(tagBatch.getSeqnumEnd());
			break;
		}
	}

	/**
	 * 判断批次是否一次性全部激活
	 */
	public boolean isAllAcitve(TagBatch tagBatch, RangeActivation rangeActivation) {
		if (rangeActivation.getSeqnumEnd().equals(tagBatch.getSeqnumEnd())
				&& rangeActivation.getSeqnumStart().equals(tagBatch.getSeqnumStart())) {
			return true;
		}
		return false;
	}

	/**
	 * 过滤码段区间是否合法
	 */
	public void filterRange(TagBatch tagBatch, RangeActivation rangeActivation) {
		if (!ValidateUtils.isInRange(rangeActivation.getSeqnumStart(), tagBatch.getSeqnumStart(),
				tagBatch.getSeqnumEnd())
				|| !ValidateUtils.isInRange(rangeActivation.getSeqnumEnd(), tagBatch.getSeqnumStart(),
						tagBatch.getSeqnumEnd())) {
			throw new RestException(HttpStatus.BAD_REQUEST, CodeMessage.NotInTagBatchRange);
		}
		List<RangeActivation> rangeActivations = rangeActivationDao.findByTagBatchId(tagBatch.getId());
		rangeActivations.forEach(item -> {
			if (ValidateUtils.isInRange(rangeActivation.getSeqnumStart(), item.getSeqnumStart(), item.getSeqnumEnd())
					|| ValidateUtils.isInRange(rangeActivation.getSeqnumEnd(), item.getSeqnumStart(),
							item.getSeqnumEnd())) {
				throw new RestException(HttpStatus.BAD_REQUEST, CodeMessage.RepeatRangeInTagBatchRange);
			}
		});
	}

	/**
	 * 激活批次区间
	 */
	public void activeRangeActivation(RangeActivation rangeActivation, TagBatch tagBatch) {
		if (rangeActivation.getActivationMethod() == 0)
			return;
		ActivationMethod method = ActivationMethod
				.fromValue(Integer.parseInt(rangeActivation.getActivationMethod().toString()));
		switch (method) {
		case Now:
			doActiveRangeActivation(rangeActivation, tagBatch);
			break;
		case Custom:
			if (new Date().after(new Date(Long.parseLong(rangeActivation.getActivationParam())))) {
				doActiveRangeActivation(rangeActivation, tagBatch);
			}
			break;
		case Delay:
			double hour = Double.parseDouble(rangeActivation.getActivationParam()) * 60 * 60 * 1000;
			if (new Date().getTime() - rangeActivation.getCreateDate().getTime() > hour) {
				doActiveRangeActivation(rangeActivation, tagBatch);
			}
			break;
		case SupplyChina:
			supplyChainActive(tagBatch);
			break;
		default:
			break;
		}
	}

	private void doActiveRangeActivation(RangeActivation rangeActivation, TagBatch tagBatch) {
		canActivation(rangeActivation, tagBatch);
		rangeActivation.setStatus(TagRangeStatus.ACTIVATED.getValue());
		rangeActivationDao.save(rangeActivation);
		publisher.publishEvent(new RangeActivationActiveEvent(tagBatch, rangeActivation, OPERATION.ACTIVAE));
	}

	public TagRangeActivationMessage createTagRangeActivationMessage(TagBatch tagBatch, RangeActivation rangeActivation,
			TagStatus status) {
		TagRangeActivationMessage message = new TagRangeActivationMessage();
		message.setDomain(tagBatch.getDomain());
		message.setFactoryId(rangeActivation.getFactoryId());
		message.setFranchiserId(rangeActivation.getFranchiserId());
		message.setProductId(rangeActivation.getProductId());
		message.setSeqnumStart(rangeActivation.getSeqnumStart());
		message.setSeqnumEnd(rangeActivation.getSeqnumEnd());
		message.setSubDomain(tagBatch.getSubDomain());
		message.setTagBatchId(rangeActivation.getTagBatchId());
		message.setStatus(status.getStatus());
		List<SeqmentCustomField> seqmentCustomFieldList = seqmentCustomFieldDao.findByrangeId(rangeActivation.getId());
		if (seqmentCustomFieldList != null) {
			Map<String, String> activationCustomFields = new HashMap<>();
			if (seqmentCustomFieldList.size() != 0) {
				for (SeqmentCustomField seqmentCustomField : seqmentCustomFieldList) {
					activationCustomFields.put(seqmentCustomField.getFieldName(), seqmentCustomField.getFieldValue());
				}
			}
			message.setActivationCustomFields(activationCustomFields);
		}
		return message;
	}

	public void activeToCloud(TagRangeActivationMessage message) {
		// TagRangeActivationMessage message = new TagRangeActivationMessage();
		// message.setDomain(rangeActivation.getDomain());
		// message.setFactoryId(rangeActivation.getFactoryId());
		// message.setFranchiserId(rangeActivation.getFranchiserId());
		// message.setProductId(rangeActivation.getProductId());
		// message.setSeqnumStart(rangeActivation.getSeqnumStart());
		// message.setSeqnumEnd(rangeActivation.getSeqnumEnd());
		// message.setSubDomain(rangeActivation.getSubDomain());
		// message.setTagBatchId(rangeActivation.getTagBatchId());
		// message.setStatus(status.getStatus());
		tagRangeActivationClient.tagRangeActivationMessageToQueue(message);
	}

	/**
	 * 判断云端码是否已经都入库，都入库才可以有激活操作
	 */
	public void canActivation(RangeActivation rangeActivation, TagBatch tagBatch) {
		TagBatchStatusRequest tagbatchRequest = new TagBatchStatusRequest();
		List<TagBatchSequenceInfo> tagBatchSequenceInfos = new ArrayList<>();
		TagBatchSequenceInfo tagBatchSequenceInfo = new TagBatchSequenceInfo();
		tagBatchSequenceInfo.setSeqNumStart(rangeActivation.getSeqnumStart());
		tagBatchSequenceInfo.setSeqNumEnd(rangeActivation.getSeqnumEnd());
		tagBatchSequenceInfo.setTagBatchId(rangeActivation.getTagBatchId());
		tagbatchRequest.setStatus(TagStatus.NOT_ACTIVATE.getStatus());
		tagBatchSequenceInfos.add(tagBatchSequenceInfo);
		tagbatchRequest.setTagBatchList(tagBatchSequenceInfos);
		TagBatchStatusResponse tagBatchResponse = tagBatchReportClient.tagBatchStatusCount(tagbatchRequest);
		Long count = tagBatchResponse.getTagBatchList().stream().findFirst().get().getCount();
		if (!count.equals(rangeActivation.getSeqnumEnd() - rangeActivation.getSeqnumStart() + 1))
			throw new RestException(HttpStatus.BAD_REQUEST, CodeMessage.ConfigNotComplete);
	}

	/**
	 * 供应链激活事件
	 */
	public void supplyChainActive(TagBatch tagBatch) throws RestException {
		TagBatchConfig tagBatchConfig = tagBatchConfigDao.findByTagBatchId(tagBatch.getId());
		EnterpriseDTO enterpriseDto = enterprisesClient.findById(tagBatch.getEseId());

		QRCodeSyncRequest request = new QRCodeSyncRequest();
		request.setBatchId(tagBatch.getId());
		request.setCodeLength(tagBatch.getCodeLength());
		request.setDirection(tagBatchConfig.getDirection());
		request.setTagCountPerLine(tagBatchConfig.getTagCountPerLine());
		request.setDuplicate(tagBatch.getDuplicate());
		request.setStartSeq(tagBatch.getSeqnumStart());
		request.setEndSeq(tagBatch.getSeqnumEnd());
		request.setEnterpriseCode(enterpriseDto.getCode());
		request.setRatio(tagBatch.getRatio());
		request.setSubDomain(tagBatch.getSubDomain());
		request.setUrlDomain(tagBatch.getDomain());
		request.setZipPassword(tagBatch.getZipPassword());
		request.setType(tagBatch.getType().getValue());
		request.setFilePath(tagBatch.getFileName());
		request.setSeqnumFilePath(tagBatch.getSeqnumFileName());
		request.setContainerName(cloudContainerConfig.getPrintFile());
		// ***
		request.setNumber(tagBatch.getTagCount());
		request.setParseTemplate(tagBatchConfig.getFieldsConfig());
		request.setQrCodeVersion(QRCodeSyncRequest.QRCodeVersion.CODE_SH);
		if (tagBatchConfig.getFileType().equals("csv"))
			request.setFileType(QRCodeSyncRequest.QRCodeFileType.CSV);
		if (tagBatchConfig.getFileType().equals("txt"))
			request.setFileType(QRCodeSyncRequest.QRCodeFileType.TXT);
		Response result = qrCodeFeignClient.syncPublishedCode(request);
		if (result.getCode() != Response.Code.SUCCESS)
			throw new RestException(HttpStatus.BAD_REQUEST, result.getMessage());
	}

}
